#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <sstream>
#include <iomanip>
#include <atomic>

std::string uuid()
{
    // 生成一个硬件随机数，效率较低
    std::random_device rd;
    // size_t num = rd();
    // 因此解决方案，就是通过一个机器随机数作为生成伪随机数的种子
    // 通过梅森旋转算法，生成一个伪随机数
    std::mt19937_64 generator(rd()); // 种种子
    std::uniform_int_distribution<int> distribution(0,255); // 生成的随机数定范围0~255
    
    std::stringstream ss;
    for(int i = 0;i<8;i++)
    {
        ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
        if(i == 3 || i == 5 || i == 7)
            ss << "-";
    }

    static std::atomic<int> sep(1); // 定义一个原子类，初始化为1，作为序号
    size_t id = sep.fetch_add(1); // 每次都增加1
    for(int i = 7;i>=0;i--)
    {
        ss << std::setw(2) << std::setfill('0') << std::hex << ((id>>(i*8)) & 0xff);
        if(i == 6) ss << "-";
    }
    return ss.str();
}

int main()
{
    for(int i = 0;i<20;i++)
    {
        std::cout<<uuid()<<std::endl;
    }
    return 0;
}
// size_t split(const std::string &str, const std::string &sep, std::vector<std::string> &result)
// {
//     // news.music.#.pop
//     // 分割的思想：
//     //  1. 从0位置开始查找指定字符的位置， 找到之后进行分割
//     //  2. 从上次查找的位置继续向后查找指定字符
//     size_t pos, idx = 0;
//     while (idx < str.size())
//     {
//         pos = str.find(sep, idx);
//         if (pos == std::string::npos)
//         {
//             // 找完了
//             result.push_back(str.substr(idx));
//             return result.size();
//         }
//         // 如果pos位置和idx相等，就证明是两个分隔符连在一起的，直接将idx增加后continue
//         if (idx == pos)
//         {
//             idx = pos + sep.size();
//             continue;
//         }

//         // 找到中间位置
//         result.push_back(str.substr(idx,pos - idx));
//         idx = pos + sep.size();
//     }
//     return result.size();
// }

// int main()
// {
//     std::string sz = ".....news.....music...#.pop...x";
//     std::vector<std::string> ret;
//     int n = split(sz,".",ret);
//     std::cout << "分割后有" << n << "个，分别是:" <<std::endl;
//     for(auto &s : ret)
//     {
//         std::cout<<s<<" ";
//     }
//     std::cout<<std::endl;
//     return 0;
// }